library(dplyr)
library(tidyverse)
library(ggpubr)
hogwarts <- read.csv("hogwarts_2024.csv")
hogwarts |> glimpse()
## Rows: 560
## Columns: 60
## $ id                                 <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …
## $ house                              <chr> "Ravenclaw", "Hufflepuff", "Ravencl…
## $ course                             <int> 4, 5, 4, 2, 2, 6, 7, 5, 2, 3, 7, 5,…
## $ sex                                <chr> "female", "male", "female", "male",…
## $ wandCore                           <chr> "unicorn hair", "phoenix feather", …
## $ bloodStatus                        <chr> "half-blood", "half-blood", "half-b…
## $ result                             <int> 94, 33, 137, 27, 67, 126, 63, 7, -8…
## $ Defence.against.the.dark.arts.exam <int> 73, 38, 52, 50, 47, 44, 51, 47, 22,…
## $ Flying.exam                        <int> 33, 36, 73, 42, 41, 52, 34, 34, 23,…
## $ Astronomy.exam                     <int> 57, 45, 66, 49, 57, 59, 58, 37, 53,…
## $ Herbology.exam                     <int> 73, 50, 62, 39, 38, 46, 59, 23, 27,…
## $ Divinations.exam                   <int> 66, 54, 72, 42, 47, 49, 42, 38, 13,…
## $ Charms.exam                        <int> 60, 70, 77, 46, 35, 55, 86, 20, 40,…
## $ History.of.magic.exam              <int> 52, 36, 60, 45, 50, 40, 55, 21, 25,…
## $ Arithmancy.exam                    <int> 61, 36, 58, 32, 76, 50, 41, 31, 24,…
## $ Care.of.magical.creatures.exam     <int> 44, 41, 70, 36, 46, 73, 29, 36, 40,…
## $ Muggle.studies.exam                <int> 64, 34, 52, 59, 50, 54, 36, 31, 43,…
## $ Study.of.ancient.runes.exam        <int> 50, 35, 59, 39, 48, 56, 47, 41, 34,…
## $ Transfiguration.exam               <int> 74, 70, 70, 15, 32, 86, 100, 31, 23…
## $ Potions.exam                       <int> 67, 38, 22, 64, 56, 60, 62, 55, 15,…
## $ week_1                             <int> 0, -5, 0, -1, 1, 5, 1, -20, 3, -20,…
## $ week_2                             <int> -10, 1, 0, 5, 20, 10, -5, 10, 1, 10…
## $ week_3                             <int> 0, -1, 1, -5, 10, -5, 3, -5, -3, 5,…
## $ week_4                             <int> 10, 1, -1, 10, -10, 10, 0, -10, -1,…
## $ week_5                             <int> 3, -5, 3, 0, -1, 20, 5, 5, -3, 5, 5…
## $ week_6                             <int> -20, 20, 0, 0, 0, 0, 0, 5, 0, -1, 1…
## $ week_7                             <int> 10, 10, 1, -3, -20, 1, 10, 3, -5, 1…
## $ week_8                             <int> 5, 5, 1, -5, 5, 5, 0, 1, 0, 20, -20…
## $ week_9                             <int> 1, 1, 3, -1, 0, 3, -20, -20, -10, 5…
## $ week_10                            <int> 20, -10, 1, 5, -1, 0, 5, -5, 5, 3, …
## $ week_11                            <int> 5, -10, 20, 0, 0, 0, 5, 10, 5, 5, 1…
## $ week_12                            <int> 5, -5, 1, -20, -10, -5, 0, 5, 1, 5,…
## $ week_13                            <int> -20, -5, 10, 0, 0, 1, -1, 10, -20, …
## $ week_14                            <int> 0, 5, 3, 10, -10, 20, 0, -20, -20, …
## $ week_15                            <int> 1, 20, 1, 0, -20, 10, 1, 3, -20, 5,…
## $ week_16                            <int> 20, 5, 5, 5, 0, 3, 10, -1, 5, 5, -1…
## $ week_17                            <int> 3, 0, 10, 5, 5, -5, -1, 10, -10, 0,…
## $ week_18                            <int> 10, 5, 5, 5, 10, -20, 0, 10, 3, 5, …
## $ week_19                            <int> -10, 0, -5, -1, 0, -1, 0, 20, 0, -3…
## $ week_20                            <int> 10, -10, 5, 10, 0, -1, -1, 10, 0, 0…
## $ week_21                            <int> 0, 5, 5, 3, 5, 0, 0, -5, -5, 5, 5, …
## $ week_22                            <int> 20, -5, 5, 0, 20, 5, -1, 0, 0, 20, …
## $ week_23                            <int> 5, 1, -3, 20, -5, 20, 0, 1, 1, 5, -…
## $ week_24                            <int> 10, -20, -20, 0, 10, 5, 5, -3, -5, …
## $ week_25                            <int> 0, -20, 1, 3, 5, 1, -5, 0, -20, 20,…
## $ week_26                            <int> 10, 10, 5, -1, 0, 5, 5, -3, 0, 20, …
## $ week_27                            <int> 5, 5, -3, 0, 20, 5, 0, -5, 10, 3, -…
## $ week_28                            <int> -3, 20, 20, 1, 10, 5, 1, 10, 0, 1, …
## $ week_29                            <int> -20, -5, 5, 5, -10, 1, 0, -3, 0, 1,…
## $ week_30                            <int> 5, 1, -5, 5, -5, -1, -20, 20, 1, 3,…
## $ week_31                            <int> 5, 5, 20, -5, -10, -3, 0, -10, 20, …
## $ week_32                            <int> -5, 1, 20, -1, -10, 5, 10, 1, 0, 0,…
## $ week_33                            <int> 0, 10, 3, 3, 0, 0, -1, 0, -20, 3, 1…
## $ week_34                            <int> 0, -1, 0, 0, 10, 3, 20, -5, 10, 3, …
## $ week_35                            <int> 5, -5, 3, -10, 3, -5, 0, 0, 0, 0, 0…
## $ week_36                            <int> 1, 5, 1, -20, 5, 20, -1, -3, 1, 3, …
## $ week_37                            <int> 0, 0, 10, -1, 10, 3, 3, 0, 20, 1, 1…
## $ week_38                            <int> 10, -1, 0, -5, 5, 5, 20, -5, -3, 0,…
## $ week_39                            <int> 3, 5, 1, 10, 20, 0, 5, 1, -5, 0, 5,…
## $ week_40                            <int> 0, 0, 5, 1, 5, 1, 10, -5, -20, 3, -…
# Changing some variables type to factors
hogwarts <- hogwarts |> mutate(
  across(c(house, course, sex, wandCore, bloodStatus), ~ as.factor(.x))
)
theme_custom <- theme(
    panel.background = element_rect(fill = "white", colour = "black"),
  panel.grid.major = element_line(colour = "grey90", size = 0.8),
    plot.title = element_text(size = 30, hjust = 0.5),
    plot.subtitle = element_text(size = 25, hjust = 0.5),
    strip.text = element_text(size = 20),
    axis.text = element_text(size = 20),
    axis.title = element_text(size = 25),
    legend.title = element_text(size = 25),
    legend.text = element_text(size = 20)
  )

Скаттерплоты

1

herbology.score <- hogwarts %>%
ggplot(aes(x = `result`,
           y = `Herbology.exam`))+
  geom_point()+
  geom_smooth(se = FALSE,
              method = "lm",
              colour = "goldenrod1")+
  
theme_custom

herbology.score

График показывает положительную корреляцию между переменными суммарный балл студента за год и оценка экзамена по травологии: чем выше значение балла за год, тем выше результат на экзамене. Оранжевая линия тренда подтверждает эту связь, но разброс точек вокруг линии указывает на наличие шума и выбросов в данных.

2

exams.score <- hogwarts %>%
  pivot_longer(cols = c(Herbology.exam, Muggle.studies.exam, Divinations.exam, Potions.exam),
               names_to = "subject",
               values_to = "exam.score") %>%
  #select(id, house, subject, exam.score) %>%
  
ggplot(aes(x = `result`,
           y = `exam.score`,
           colour = `house`))+ 
  scale_colour_manual(values = c("Gryffindor" = "#C50000", 
                             "Hufflepuff" = "#ECB939", 
                             "Ravenclaw" = "#41A6D9", 
                             "Slytherin" = "#1F5D25"))+
  geom_point()+
  geom_smooth(se = FALSE,
              method = "lm")+
  facet_wrap(~ subject)+

  
theme_custom

exams.score

Интерпретация: по экзаменам прорицания, гербология и маггловедению надблюдается примерно одинаковая картина - тренды оценок студентов разных факультетов похожи (наблюдается положительная корреляция между суммарным баллом студента и оценкой за экзамен), однако у студентов факультета Слизерин наблюдается большее число студентов с общим баллом меньше чем -100, и соответствующей низкой оценкой за экзаемн. По экзамену зельеварение студенты Слизерина стабильно получают высокий балл (почти все получили балл больше 75), независимо от суммарного балла (и можно наблюдать две группы студентов: высокий суммарный балл - высокая оценка за экзамен, низкий суммарный балл - высокая оценка за экзамен). Студенты остальных факультетов получают значительно более низкую оценку за экзамен по зельеварению, и можно наблюдать слабую отрицательную корреляцию между суммарным баллом и оценкой за экзамен. Можно даже сказать что студенты Грифииндора, Хаффлпаффа и Рэйвенкло получают стабильно средне-низкие (не выше 75 баллов) оценки за экзамен по зельеварению.

3

exams.score.slytherin <- hogwarts %>%
  pivot_longer(cols = c(Herbology.exam, Muggle.studies.exam, Divinations.exam, Potions.exam),
               names_to = "subject",
               values_to = "exam.score") %>%
  select(id, house, subject, exam.score, result) %>%
  
ggplot(aes(x = `result`,
           y = `exam.score`,
           colour = `house`,
           linetype = ifelse(house == "Slytherin", "Slytherin", "Other Houses")))+ 
  scale_colour_manual(values = c("Gryffindor" = "#C50000", 
                             "Hufflepuff" = "#ECB939", 
                             "Ravenclaw" = "#41A6D9", 
                             "Slytherin" = "#1F5D25"),
                      name ="House")+
  #scale_linetype_manual(name = "Trend Line Type")+
  labs(linetype = "Trend Line Type")+
  
  geom_point()+
  geom_smooth(se = FALSE,
              method = "lm",
              aes(group = ifelse(house == "Slytherin", house, "Other Houses")))+
  facet_wrap(~ subject)+
  
theme_custom

exams.score.slytherin

## geom_col ### 1

col1 <- hogwarts %>%
  select(id, bloodStatus, week_1:week_17) %>%
  rowwise %>%
  mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
  group_by(bloodStatus) 
  
ggplot(col1)+
  geom_col(aes(x = bloodStatus,
               y = sum(total.score),
               fill = bloodStatus))+

theme_custom

col1
## # A tibble: 560 × 20
## # Groups:   bloodStatus [3]
##       id bloodStatus week_1 week_2 week_3 week_4 week_5 week_6 week_7 week_8
##    <int> <fct>        <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>
##  1     1 half-blood       0    -10      0     10      3    -20     10      5
##  2     2 half-blood      -5      1     -1      1     -5     20     10      5
##  3     3 half-blood       0      0      1     -1      3      0      1      1
##  4     4 half-blood      -1      5     -5     10      0      0     -3     -5
##  5     5 half-blood       1     20     10    -10     -1      0    -20      5
##  6     6 muggle-born      5     10     -5     10     20      0      1      5
##  7     7 half-blood       1     -5      3      0      5      0     10      0
##  8     8 half-blood     -20     10     -5    -10      5      5      3      1
##  9     9 half-blood       3      1     -3     -1     -3      0     -5      0
## 10    10 pure-blood     -20     10      5      1      5     -1     10     20
## # ℹ 550 more rows
## # ℹ 10 more variables: week_9 <int>, week_10 <int>, week_11 <int>,
## #   week_12 <int>, week_13 <int>, week_14 <int>, week_15 <int>, week_16 <int>,
## #   week_17 <int>, total.score <int>

Гипотеза: магглорожденных студентов сравнительно мало и им явно приходится сложно и трудно в первом семестре, этим можно объяснить их низкий балл. А различия в балле полукровок и чистокровных также можно объяснить количеством студентов (полукровок намного больше, чем чистокровных).

2

blood.status.result <- hogwarts %>%
  rowwise() %>%
  mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
  group_by(bloodStatus) %>%
  summarise(blood.st.total.score = sum(total.score),
            num_students = n())


#col2 <- hogwarts %>%
  #select(id, bloodStatus, week_1:week_17) %>%
   
  #rowwise() %>%
  #mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
  #group_by(bloodStatus) 
  
ggplot(blood.status.result, aes(x = fct_reorder(bloodStatus, blood.st.total.score, .desc = TRUE),
                                y = blood.st.total.score,
                                fill = bloodStatus))+
  geom_col()+
  geom_label(aes(label = num_students), size = 7)+
  
  labs(x = "blood status",
       y = "total score")+

theme_custom

Интерпретация: из графика видно, что студентов-полукровок больше, чем остальных студентов, а число чистокровных студентов больше чем число магглорожденных студентов. Соответственно и баллов было заработано пропорциональное количество. Гипотеза соотносится с гипотезой из пункта 1.

3

blood.status.result <- hogwarts %>%
  rowwise() %>%
  mutate(total.score = sum(c_across(week_1:week_17), na.rm = TRUE)) %>%
  group_by(bloodStatus, sex) %>%
  summarise(blood.st.total.score = sum(total.score),
            num_students = n()) %>%
  mutate(blood.st.sex = paste0(bloodStatus, " ", sex))

ggplot(blood.status.result, 
       aes(y = fct_reorder(blood.st.sex, blood.st.total.score, .desc = FALSE), 
           x = blood.st.total.score,))+
  
  geom_col(aes(fill = bloodStatus))+
  
  #theme(axis.text.x = element_text(angle = 20))+
  
  geom_label(aes(label = num_students,
                 x = 9000), size = 7)+
  
  labs(y = "blood status",
       x = "score",
       title = "distribution of student scores for 1 semester depending on gender and blood status")+
  scale_x_continuous(breaks = seq(0, 10000, 1000))+ #labels = paste0(seq(0, 10000, 1000), " p."))+

theme_custom

#ggsave("blood.status_and_sex_result_plot.png", blood.status.result, width = 20, height = 16, units = "in", dpi = 300)

Комментарий к графику: в задании сказано расположить в порядке убывания, вроде так и расположила(сверху вниз убывает, но в аргументе .desc = FALSE) Также в задании не указано, какую информацию должны содержать текстовые метки в этом задании - оставила как в предыдущем, количество студентов в коле.

4

coord_flip()

Эта функция разворачивает графики, меняет местами оси x и y. Думаю, эта функция бывает полезна, когда внутри ggplot и geom_ лежит много аргументов, и сложно будет вручную менять оси местами. Или когда строим несколько графиков, и аргументы заложены внутри ggplot, и чтобы не менять их местами можно использовать coord_flip, это будет быстрее и удобнее (и отменять эту функцию тоже удобнее, чем обратно вручную менять оси местами) Плюсы: быстрее и удобнее поменять оси местами, не изменяя код; работает со многими функциями внутри ggplot Минусы: не позволяет вручную настраивать, что именно отобразится на оси, не гибка; может напортачить со сложными графиками

Разное

1

potion_vs_runes <- hogwarts %>%
  mutate(id = as.factor(id)) %>%
  pivot_longer(cols = c(Potions.exam, Study.of.ancient.runes.exam),
               names_to = "subject",
               values_to = "exam.score") %>%
  select(id, subject, exam.score, house, sex, course)

  plot3.1.1 <- ggplot(potion_vs_runes)+
    geom_density(aes(x = exam.score, fill = subject),
                 alpha = 0.5
                 )+
    #facet_grid(.~sex)+
    labs(x = "exam score")+
    theme(legend.position = "none")+  
theme_custom

plot3.1.2 <- ggplot(potion_vs_runes)+
    geom_histogram(aes(x = exam.score, fill = subject),
                   colour = "black",
                   bins = 20,
                   alpha = 0.5,
                   position = "identity"
                   )+
  labs(x = "exam score")+
  theme(legend.position = "none")+
theme_custom


plot3.1.3 <- ggplot(potion_vs_runes)+
  geom_boxplot(aes(x = fct_reorder(house, exam.score, .desc = TRUE),  
                   y = exam.score, 
                   fill = subject),
               width = 0.5, 
               size = 1.2)+
    labs(x = "exam score")+
    theme(legend.position = "none")+
  theme_custom



#ggarrange(plotlist = list(plot3.1.1, plot3.1.2, plot3.1.3, plot3.1.3), ncol = 2, nrow = 2)
comb.plot <- ggarrange(
  ggarrange(plot3.1.1, plot3.1.2, ncol = 2),   # Верхняя строка: два графика
  plot3.1.3,                                   # Нижняя строка: один график
  ncol = 1,                                    # Внешняя структура в один столбец
  heights = c(1, 1.5),
  common.legend = TRUE, # Одна общая легенда
  legend = "bottom"                            # Легенда снизу
)
annotate_figure(comb.plot, top = text_grob("Comparison of Potion exam score and Study of ancient runes exam score", 
                                           size = 26,
                                           face = "bold"))

#title = "Comparison of Potion exam score and Study of ancient runes exam score",

2

blood.and.potion <- hogwarts %>%
  group_by(bloodStatus) %>%
  summarise(meanPotionScore = mean(Potions.exam) %>% round(2),
            Min = (min(Potions.exam) %>% round(2)),
            Max = (max(Potions.exam) %>% round(2))
            )

ggplot(blood.and.potion)+
  #geom_col(aes(x = bloodStatus,
             #y = meanPotionScore,
             #fill = bloodStatus))+
  
  geom_pointrange(aes(x = bloodStatus,
                        y = meanPotionScore, 
                        ymin = Min,
                        ymax = Max,
                        colour = bloodStatus),
                  linewidth =2,
                  fatten = 10)+
  labs(title = "Distribution of average potions exam scores among students with different blood
status", 
       y = "Potiom exam score",
       caption = "dots - average score, lines - min-max")+
  
  theme(legend.position = "none",
        plot.caption = element_text(size = 22, hjust = 1))+

#ggplot(aes(x = fct_reorder(bloodStatus, Potions.exam, .desc = TRUE), 
           #y = Potions.exam))+
  #geom_boxplot(aes(fill = bloodStatus),
               #notch = TRUE)+
  
  theme_custom

blood.and.potion
## # A tibble: 3 × 4
##   bloodStatus meanPotionScore   Min   Max
##   <fct>                 <dbl> <dbl> <dbl>
## 1 half-blood             47.1     0   100
## 2 muggle-born            37.4     1   100
## 3 pure-blood             50.0     0   100
blood.potions <- hogwarts %>%
  group_by(house, bloodStatus) %>%
  summarize(mean.Potions.exam = mean(Potions.exam, na.rm = TRUE) %>% round(2)
            #Min = (min(Potions.exam) %>% round(2)),
            #Max = (max(Potions.exam) %>% round(2))
            )

ggplot(blood.potions)+
  #geom_col(aes(x = bloodStatus,
             #y = meanPotionScore,
             #fill = bloodStatus))+
  
  geom_point(aes(x = bloodStatus,
                 y = mean.Potions.exam,
                 colour = house),
             size =8)+
  scale_colour_manual(values = c("Gryffindor" = "#C50000", 
                             "Hufflepuff" = "#ECB939", 
                             "Ravenclaw" = "#41A6D9", 
                             "Slytherin" = "#1F5D25"),
                      name ="House")+
  theme_custom

blood.potions
## # A tibble: 12 × 3
## # Groups:   house [4]
##    house      bloodStatus mean.Potions.exam
##    <fct>      <fct>                   <dbl>
##  1 Gryffindor half-blood               33.7
##  2 Gryffindor muggle-born              25.6
##  3 Gryffindor pure-blood               37.8
##  4 Hufflepuff half-blood               35.3
##  5 Hufflepuff muggle-born              34.8
##  6 Hufflepuff pure-blood               37.4
##  7 Ravenclaw  half-blood               34.5
##  8 Ravenclaw  muggle-born              30.1
##  9 Ravenclaw  pure-blood               43.7
## 10 Slytherin  half-blood               84.4
## 11 Slytherin  muggle-born              85  
## 12 Slytherin  pure-blood               82.8
#ggarrange()

Комментарий: объединить последние два графика

potion_vs_runes <- hogwarts %>%
  #summarise(meanPotion = mean(`Potion.exam`), meanRunes = mean(`Study.of.ancient.runes.exam
#`)) %>%
  pivot_longer(cols = c(Potions.exam, Study.of.ancient.runes.exam),
               names_to = "subject",
               values_to = "exam.score") %>%
  select(id, subject, exam.score, house)

  test_col <- ggplot(potion_vs_runes, aes(x = subject, y = exam.score))+
    geom_col(aes(fill = house))+
  theme_custom
  test_col

  #test_pie <- ggplot(potion_vs_runes)+
   #geom_col(aes(x = '', y = exam.score, fill = subject))+
    
    #coord_polar(theta = "y")+

    #scale_fill_manual(values = c("Gryffindor" = "#C50000", 
                            # "Hufflepuff" = "#ECB939", 
                            # "Ravenclaw" = "#41A6D9", 
                           #  "Slytherin" = "#1F5D25"),
                    #  name ="House")+
  #theme_custom
  #test_pie
#ggarrange(plotlist = list(test_pie, test_col), ncol = 2)